package org.tis.tools.senior.module.developer.entity.vo;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.tis.tools.senior.module.developer.entity.*;
import org.tis.tools.senior.module.developer.entity.enums.ContributionType;
import org.tis.tools.senior.module.developer.entity.enums.DeployWhere;
import org.tis.tools.senior.module.developer.entity.enums.ProjectType;
import org.tis.tools.senior.module.developer.util.DeveloperUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * description:
 *
 * @author zhaoch
 * @date 2018/6/22
 **/
@Data
public class DeliveryProjectDetail {

    /**
     * 工程名
     */
    private String projectName;

    /**
     * 工程类型
     */
    private String projectType;

    /**
     * 编译为
     */
    private List<DeliveryPatchDetail> deliveryPatchDetails;


    public Set<String> getPatchType() {
        Set<String> count = new HashSet<>();
        this.deliveryPatchDetails.forEach(dpd -> {
            String[] split = dpd.getPatchType().split(",");
            for (String p : split) {
                count.add(p);
            }
        });
        return count;

    }

    public static List<DeliveryProjectDetail> getDeliveryListDetail(List<SDeliveryList> deliveryLists,
                                                                List<SProject> projects) {
        Map<String, SProject> pjMap = projects.stream().collect(Collectors.toMap(SProject::getProjectName, p -> p));
        return getDeliveryPatchDetail(pjMap, deliveryLists);
    }

    public static List<DeliveryProjectDetail> getCheckDeliveryDetail(List<SCheckList> checkLists, List<SProject> projects) {
        Map<String, SProject> pjMap = projects.stream().collect(Collectors.toMap(SProject::getProjectName, p -> p));
        List<DeliveryProjectDetail> details = new ArrayList<>();
        checkLists.stream().collect(Collectors.groupingBy(SCheckList::getPartOfProject))
                .forEach((p, l) -> {
                    DeliveryProjectDetail detail = new DeliveryProjectDetail();
                    detail.setProjectName(p);
                    detail.setProjectType(pjMap.get(p).getProjectType().getValue().toString());
                    List<DeliveryPatchDetail> dpts = new ArrayList<>();
                    if (pjMap.get(p).getProjectType().equals(ProjectType.IBS)) {
                        l.stream().collect(Collectors.groupingBy(SCheckList::getPatchType)).forEach((pt, list) -> {
                            list.stream().collect(Collectors.groupingBy(SCheckList::getDeployWhere)).forEach((wh, ddw) -> {
                                DeliveryPatchDetail dpt = new DeliveryPatchDetail();
                                dpt.setPatchType(pt);
                                dpt.setDeployWhere(DeveloperUtils.getDeployWhere(pt, wh));
                                dpt.setFileList(ddw);
                                dpts.add(dpt);
                                detail.setDeliveryPatchDetails(dpts);
                            });
                        });
                    } else {
                        l.stream().collect(Collectors.groupingBy(SCheckList::getPatchType)).forEach((pt, list) -> {
                            DeliveryPatchDetail dpt = new DeliveryPatchDetail();
                            dpt.setPatchType(pt);
                            dpt.setDeployWhere(DeveloperUtils.getDeployWhere(pt, list.get(0).getDeployWhere()));
                            dpt.setFileList(list);
                            dpts.add(dpt);
                            detail.setDeliveryPatchDetails(dpts);
                        });
                    }
                    details.add(detail);
                });
        return details;
    }

    public static List<DeliveryProjectDetail> getStandardDetail(List<SStandardList> standardLists, List<SProject> projects) {
        Map<String, SProject> pjMap = projects.stream().collect(Collectors.toMap(SProject::getProjectName, p -> p));
        List<SDeliveryList> deliveryLists = new ArrayList<>();
        standardLists.forEach(standardList ->{
            SDeliveryList deliveryList = new SDeliveryList();
            BeanUtils.copyProperties(standardList, deliveryList);
            deliveryLists.add(deliveryList);
        });

        return getDeliveryPatchDetail(pjMap, deliveryLists);
    }

    public static List<DeliveryProjectDetail> getStashDetail(List<SStashList> stashLists, List<SProject> projects) {
        Map<String, SProject> pjMap = projects.stream().collect(Collectors.toMap(SProject::getProjectName, p -> p));
        List<SDeliveryList> deliveryLists = new ArrayList<>();
        stashLists.forEach(standardList ->{
            SDeliveryList deliveryList = new SDeliveryList();
            BeanUtils.copyProperties(standardList, deliveryList);
            deliveryLists.add(deliveryList);
        });
        return getDeliveryPatchDetail(pjMap, deliveryLists);
    }

    public static List<DeliveryProjectDetail> getRollbackDetail(List<SRollbackList> rollbackLists, List<SProject> projects) {
        Map<String, SProject> pjMap = projects.stream().collect(Collectors.toMap(SProject::getProjectName, p -> p));
        List<SDeliveryList> deliveryLists = new ArrayList<>();
        rollbackLists.forEach(rollbackList ->{
            SDeliveryList deliveryList = new SDeliveryList();
            BeanUtils.copyProperties(rollbackList, deliveryList);
            deliveryLists.add(deliveryList);
        });
        return getDeliveryPatchDetail(pjMap, deliveryLists);
    }

    public static List<DeliveryProjectDetail> getRepealDetail(List<SRepealList> repealLists, List<SProject> projects) {
        Map<String, SProject> pjMap = projects.stream().collect(Collectors.toMap(SProject::getProjectName, p -> p));
        List<DeliveryProjectDetail> details = new ArrayList<>();
        repealLists.stream().collect(Collectors.groupingBy(SRepealList::getPartOfProject))
                .forEach((p, l) -> {
                    DeliveryProjectDetail detail = new DeliveryProjectDetail();
                    detail.setProjectName(p);
                    detail.setProjectType(pjMap.get(p).getProjectType().getValue().toString());
                    List<DeliveryPatchDetail> dpts = new ArrayList<>();
                    if (pjMap.get(p).getProjectType().equals(ProjectType.IBS)) {
                        l.stream().collect(Collectors.groupingBy(SRepealList::getPatchType)).forEach((pt, list) -> {
                            list.stream().collect(Collectors.groupingBy(SRepealList::getDeployWhere)).forEach((wh, ddw) -> {
                                DeliveryPatchDetail dpt = new DeliveryPatchDetail();
                                dpt.setPatchType(pt);
                                dpt.setDeployWhere(DeveloperUtils.getDeployWhere(pt, wh));
                                dpt.setFileList(ddw);
                                dpts.add(dpt);
                                detail.setDeliveryPatchDetails(dpts);
                            });
                        });
                    } else {
                        l.stream().collect(Collectors.groupingBy(SRepealList::getPatchType)).forEach((pt, list) -> {
                            DeliveryPatchDetail dpt = new DeliveryPatchDetail();
                            dpt.setPatchType(pt);
                            dpt.setDeployWhere(DeveloperUtils.getDeployWhere(pt, list.get(0).getDeployWhere()));
                            dpt.setFileList(list);
                            dpts.add(dpt);
                            detail.setDeliveryPatchDetails(dpts);
                        });
                    }
                    details.add(detail);
                });
        return details;
    }

    /**
     * 获取部署类型
     * @param patchType 导出类型
     * @param deployConfig 导出配置
     * @return
     */
    public static String generateDeployWhereString(String patchType, String deployConfig) {
        JSONArray configs = JSONArray.parseArray(deployConfig);
        JSONObject j = new JSONObject();
        String[] types = patchType.split(",");
        for (String type : types) {
            if (StringUtils.isNotBlank(type)) {
                for (Object config : configs) {
                    JSONObject jsonObject = JSONObject.parseObject(config.toString());
                    if (type.equals(jsonObject.getString("exportType"))) {
                        j.put(type, jsonObject.getString("deployType"));
                    }
                }

            }
        }
        return j.toJSONString();
    }

    public static List<DeliveryProjectDetail> getDeliveryPatchDetail( Map<String, SProject> pjMap, List<SDeliveryList> deliveryLists){
        List<DeliveryProjectDetail> details = new ArrayList<>();
        deliveryLists.stream().collect(Collectors.groupingBy(SDeliveryList::getPartOfProject))
            .forEach((p, l) -> {
                DeliveryProjectDetail detail = new DeliveryProjectDetail();
                detail.setProjectName(p);
                detail.setProjectType(pjMap.get(p).getProjectType().getValue().toString());
                List<DeliveryPatchDetail> dpts = new ArrayList<>();
                if (pjMap.get(p).getProjectType().equals(ProjectType.IBS)) {
                    l.stream().collect(Collectors.groupingBy(SDeliveryList::getPatchType)).forEach((pt, list) -> {
                        list.stream().collect(Collectors.groupingBy(SDeliveryList::getDeployWhere)).forEach((wh, ddw) -> {
                            DeliveryPatchDetail dpt = new DeliveryPatchDetail();
                            dpt.setPatchType(pt);
                            dpt.setDeployWhere(DeveloperUtils.getDeployWhere(pt, wh));
                            dpt.setFileList(ddw);
                            dpts.add(dpt);
                            detail.setDeliveryPatchDetails(dpts);
                        });
                    });
                } else {
                    l.stream().collect(Collectors.groupingBy(SDeliveryList::getPatchType)).forEach((pt, list) -> {
                        DeliveryPatchDetail dpt = new DeliveryPatchDetail();
                        dpt.setPatchType(pt);
                        dpt.setDeployWhere(DeveloperUtils.getDeployWhere(pt, list.get(0).getDeployWhere()));
                        dpt.setFileList(list);
                        dpts.add(dpt);
                        detail.setDeliveryPatchDetails(dpts);
                    });
                }
                details.add(detail);
            });
        return details;
    }


    /**
     * 根据构建包类型获取部署类型
     * @param patchType
     * @param deployConfig
     * @return
     */
    public static String getDeployWhereBuildPackType(String patchType, String deployConfig, String contributionType) {
        JSONArray configs = JSONArray.parseArray(deployConfig);
        JSONObject j = new JSONObject();
        String[] types = patchType.split(",");
        for (String type : types) {
            if (StringUtils.isNotBlank(type)) {
                here:
                for (Object config : configs) {
                    JSONObject jsonObject = JSONObject.parseObject(config.toString());
                    if (type.equals(jsonObject.getString("exportType"))) {
                        String[] deployWhere = jsonObject.getString("deployType").split(",");
                        if(deployWhere.length > 1){
                            if(!(ContributionType.COMMONRESOURCE.getValue().equals(contributionType) ||
                                    ContributionType.PRODUCT.getValue().equals(contributionType))){
                                for (String where:deployWhere){
                                    if(where.equals(DeployWhere.BS_WORK_USER.getValue())){
                                        j.put(type, where);
                                        continue here;
                                    }
                                }
                            }
                        }
                        j.put(type, jsonObject.getString("deployType"));
                    }
                }

            }
        }
        return j.toJSONString();
    }



}
